package net.fornwall.eclipsecoder.actions;

import java.beans.XMLDecoder;

import net.fornwall.eclipsecoder.languages.LanguageSupport;
import net.fornwall.eclipsecoder.languages.LanguageSupportFactory;
import net.fornwall.eclipsecoder.stats.ProblemStatement;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IObjectActionDelegate;
import org.eclipse.ui.IWorkbenchPart;

/**
 * TODO: Use {@link IWorkspace#validatePath(String, int)} to validate path name.
 */
class NewProjectDialog extends Dialog {

	private Text projectNameField;

	private Combo languageCombo;

	private String projectName;
	private String language;

	public NewProjectDialog(Shell parentShell) {
		super(parentShell);
		// getShell().setText("Create new project");
	}

	@Override
	public boolean close() {
		projectName = projectNameField.getText();
		language = languageCombo.getText();
		return super.close();
	}

	@Override
	protected Control createDialogArea(Composite parent) {
		Composite container = (Composite) super.createDialogArea(parent);
		final GridLayout gridLayout = new GridLayout();
		gridLayout.numColumns = 2;
		container.setLayout(gridLayout);

		final Label descriptionLabel = new Label(container, SWT.NONE);
		descriptionLabel.setLayoutData(new GridData(GridData.BEGINNING,
				GridData.CENTER, false, false, 2, 1));
		descriptionLabel
				.setText("Specify the name for the project to create and the programming language to use.");

		final Label nameLabel = new Label(container, SWT.NONE);
		nameLabel.setLayoutData(new GridData(GridData.END, GridData.CENTER,
				false, false));
		nameLabel.setText("Project name:");

		projectNameField = new Text(container, SWT.BORDER);
		projectNameField.setLayoutData(new GridData(GridData.FILL,
				GridData.CENTER, true, false));

		final Label languageLabel = new Label(container, SWT.NONE);
		GridData data = new GridData(GridData.END, GridData.CENTER, false,
				false);
		data.horizontalIndent = 20;
		languageLabel.setLayoutData(data);
		languageLabel.setText("Programming language:");

		languageCombo = new Combo(container, SWT.DROP_DOWN | SWT.READ_ONLY);
		languageCombo.setItems(LanguageSupportFactory.supportedLanguages()
				.toArray(new String[0]));
		languageCombo.setText(languageCombo.getItem(0));
		languageCombo.setLayoutData(new GridData(GridData.FILL,
				GridData.CENTER, true, false));

		return container;
	}

	public String getProgrammingLanguage() {
		return language;
	}

	public String getProjectName() {
		return projectName;
	}

}

public class GenerateSourceAction implements IObjectActionDelegate {

	IFile selectedFile;

	IWorkbenchPart targetPart;

	public void run(IAction action) {
		try {
			NewProjectDialog dialog = new NewProjectDialog(targetPart.getSite()
					.getShell());
			if (dialog.open() != Window.OK) {
				return;
			}

			XMLDecoder decoder = new XMLDecoder(selectedFile.getContents());
			ProblemStatement problem = (ProblemStatement) decoder.readObject();
			decoder.close();

			LanguageSupport languageSupport = LanguageSupportFactory
					.createLanguageSupport(dialog.getProgrammingLanguage());
			languageSupport.setProjectName(dialog.getProjectName());
			languageSupport.createProject(problem);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@SuppressWarnings("unchecked")
	public void selectionChanged(IAction action, ISelection selection) {
		StructuredSelection fileSelection = (StructuredSelection) selection;
		if (fileSelection.getFirstElement() instanceof IFile) {
			selectedFile = (IFile) fileSelection.getFirstElement();
		}
	}

	public void setActivePart(IAction action, IWorkbenchPart targetPart) {
		this.targetPart = targetPart;
	}

}
